package reflect;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Scanner;

/*
* JAVA反射机制
* 反射是java的动态机制，允许程序在“运行期间”在确定如：对象的实例化，方法的调用，属性的操作等。
* 反射机制可以提高代码的灵活性和适应性，但是会带来较多的系统开销和较慢的运行效率
* 因此反射机制不能过度被依赖
* */
public class ReflectDemo1 {
    public static void main(String[] args) throws ClassNotFoundException {
        /*
        * 反射机制使用的第一步：获取待操作的类的类对象
        * 类对象：Class类的实例
        * JVM内部每一个被加载的类都有且只有一个Class的实例与之对应
        * JVM加载一个类时会读取该类的.Class文件然后将其载入到JVM内部，与此同时
        * 会实例化一个Class的实例，用该实例记录被加载的类的信息(类名，方法，构造器等)
        * 获取一个类的类对象方式：
        *
        * 1.类名.class
        * Class cls = String.class;//获取String的类对象
        * Class cls = int.class;//获取int的类对象(基本类型只有这一种方式获取)
        *
        * 2.Class.forName(String className)
        * 根据类的完全限定(包名.类名)名加载并获取该类的类对象
        * Class cls = Class.forName("java.lang.String");
        *
        * 3.ClassLoader类加载器方式
        * */
        //1.
        //Class cls = String.class;
        //Class cls = ArrayList.class;
        //String name = cls.getName();
        //System.out.println(name); //完全限定名(包名.类名) java.lang.String
        //name = cls.getSimpleName();
        //System.out.println(name);//类名 String
        //2.
        //Class cls = Class.forName("java.lang.String");
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入一个类名：");
        String className = scanner.nextLine();
        Class cls = Class.forName(className);
        /*
        * Package getPackage()
        * 通过类对象获取其表示的类的包信息
        * Class，它的每一个实例用于表示一个类的信息
        * Package，它的每一个实例用于表示一个包的信息
        * Method,它的每一个实例用于表示一个方法
        * Constructor,它的每一个实例用于表示一个构造器
        * Filed,它的每一个实例用于表示一个属性
        * */
        String packageName = cls.getPackage().getName();
        System.out.println(packageName);// 包名 java.lang
        //通过类对象获取其表示的类中的所有公开方法(包含从超类中继承的方法)
        Method[] methods = cls.getMethods();
        for (Method method : methods){
            //每一个Method对象也提供了许多get方法可以获取其表示的方法的相关信息
            System.out.println(method.getName()); //输出方法名
        }
    }
}
